package org.lq.dlz.util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

/**
* 时间工具类
* @author wuyu
* @description
**/
public class DateUtils
{
    public static String YYYY = "yyyy";

    public static String YYYY_MM = "yyyy-MM";

    public static String YYYY_MM_DD = "yyyy-MM-dd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    /**
     * 使用线程  对象独享
     *
     */
    private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>();

    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Date getNowDate()
    {
        return new Date();
    }
    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Timestamp getTimestamp()
    {
    	//如果Date类型添加到数据 只有 年-月-日 00:00:00
    	//Timestamp 年月日包含时分秒
        return new Timestamp(System.currentTimeMillis());
    }
    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate()
    {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static final String getTime()
    {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static final String dateTimeNow()
    {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static final String dateTimeNow(final String format)
    {
        return parseDateToStr(format, new Date());
    }

    public static final String dateTime(final Date date)
    {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    public static final String parseDateToStr(final String format, final Date date)
    {
        return new SimpleDateFormat(format).format(date);
    }

    public static final Date dateTime(final String format, final String ts)
    {
        try
        {
            return new SimpleDateFormat(format).parse(ts);
        }
        catch (ParseException e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static final String datePath()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static final String dateTime()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }

    /**
     * 获取时间格式化对象
     * @return
     */
    public static DateFormat getDateFormat() {

        DateFormat df = threadLocal.get();
        if (df == null) {
            df = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
            threadLocal.set(df);
        }
        return df;
    }

    /**
     * 根据指定格式格式化时间
     * @param date
     * @return
     * @throws ParseException
     */
    public static String formatDate(Date date) {

        return getDateFormat().format(date);
    }

    public static String dateToStr(Date date, int type) {

        switch (type) {
            case 0:
                return dateToStr(date);
            case 1:
                return dateToStr(date, "yyyy/MM");
            case 2:
                return dateToStr(date, "yyyyMMdd");
            case 11:
                return dateToStr(date, "yyyy-MM-dd");
            case 3:
                return dateToStr(date, "yyyyMM");
            case 4:
                return dateToStr(date, "yyyy/MM/dd HH:mm:ss");
            case 5:
                return dateToStr(date, "yyyyMMddHHmmss");
            case 6:
                return dateToStr(date, "yyyy/MM/dd HH:mm");
            case 7:
                return dateToStr(date, "HH:mm:ss");
            case 8:
                return dateToStr(date, "HH:mm");
            case 9:
                return dateToStr(date, "HHmmss");
            case 10:
                return dateToStr(date, "HHmm");
            case 12:
                return dateToStr(date, "yyyy-MM-dd HH:mm:ss");
            case 13:
                return dateToStr(date, "yyyy-MM-dd HH:mm");
            case 14:
                return dateToStr(date, "yyyyMMddHHmmssSSS");
        }
        throw new IllegalArgumentException("Type undefined : " + type);
    }


    public static String dateToStr(Date date, String pattern) {

        if ((date == null) ){
            return null;
        }
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        return formatter.format(date);
    }
    public static String dateToStr(Date date) {

        return dateToStr(date, "yyyy/MM/dd");
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDaysByMillisecond(Date date1,Date date2)
    {
        int days = (int) ((date2.getTime() - date1.getTime()) / (1000*3600*24));
        return days;
    }
    public static  List<String> getMonthBetween(String minDate,String maxDate){
        ArrayList<String> result = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.YYYY_MM);//格式化为年月
        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();
        try {
            min.setTime(sdf.parse(minDate));
            min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
            max.setTime(sdf.parse(maxDate));
            max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
            Calendar curr = min;
            while (curr.before(max)) {
                result.add(sdf.format(curr.getTime()));
                curr.add(Calendar.MONTH, 1);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }
    
    
    /**
     * 获取两个时间之间的日期集合
     * @param startDateStr 开始时间
     * @param endDateStr 结束时间
     * @param format 时间格式
     * @return 日期集合
     */
    public static List<String> getDatesBetweenTwoDate(String startDateStr, String endDateStr, String format ) {
        List<String> result =new ArrayList<>();
        List<Date> dates = new ArrayList<Date>();
        try{
            Date beginDate = dateTime(format,startDateStr);
            Date endDate = dateTime(format,endDateStr);
            dates.add(beginDate);// 把开始时间加入集合
            Calendar cal = Calendar.getInstance();
            // 使用给定的 Date 设置此 Calendar 的时间
            cal.setTime(beginDate);
            boolean bContinue = true;
            while (bContinue) {
                // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
                cal.add(Calendar.DAY_OF_MONTH, 1);
                // 测试此日期是否在指定日期之后
                if (endDate.after(cal.getTime())) {
                    dates.add(cal.getTime());
                } else {
                    break;
                }
            }
            dates.add(endDate);// 把结束时间加入集合
            if(CollectionUtils.isNotEmpty(dates)){
                for(int i=0;i<dates.size();i++) {
                    result.add(dateToStr(dates.get(i),format));
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }

        return result;
    }

    /**
     *获取当前月份第一天
     * @return
     */
    public static String getMinMonthDate(){
        SimpleDateFormat format = new SimpleDateFormat(YYYY_MM_DD);
        Calendar cal_1=Calendar.getInstance();//获取当前日期 
        cal_1.add(Calendar.MONTH, -1);
        cal_1.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天        
        String firstDay = format.format(cal_1.getTime());
        return firstDay;
    }

    /**
     * 获取当前月份最后一天
     * @return 当月最后一天
     */
    public static String getMaxMonthDate() {
        SimpleDateFormat dft = new SimpleDateFormat(YYYY_MM_DD);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return dft.format(calendar.getTime());
    }
}
